/*
 * Copyright 2008 echo.khannedy@gmail.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ["Let's ROCK with JAVA"]
 * 
 * ["echo.khannedy@gmail.com"]
 * ["http://eecchhoo.wordpress.com/"]
 */
package open.usu.swing;

import open.usu.awt.util.GraphicUtilities;
import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D.Double;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import open.usu.swing.event.TransitionListener;
import open.usu.swing.event.TransitionEvent;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.timing.interpolation.PropertySetter;

/**
 * EImageTransition merupakan komponen yang digunakan untuk efect - efect yang berhubungan 
 * dengan {@link Image} (Gambar). Komponen ini berguna seperti komponen {@link ETransition}
 * hanya saja, untuk {@link ETransition} menampilkan efect transisi untuk Bentuk, namun
 * Komponen ini menampilkan efect untuk gambar
 * 
 * @author usu
 * @author <a href="mailto:echo.khannedy@gmail.com">echo.khannedy@gmail.com</a>
 * @see <a href="http://eecchhoo.wordpress.com/">http://eecchhoo.wordpress.com/</a>
 * @see <a href="http://biosmansa.wordpress.com/">http://biosmansa.wordpress.com/</a>
 * @see <a href="http://code.google.com/p/eglasspane/">http://code.google.com/p/eglasspane/</a>
 */
public class EImageTransition extends JComponent {

    // <editor-fold defaultstate="collapsed" desc="Variable Code">
    private static final long serialVersionUID = 6699813793638510213L;
    /**
     * Properti untuk imageTransition
     */
    public static final String PROPERTY_IMAGE_TRANSITION = "PROPERTY_IMAGE_TRANSITION";
    /**
     * Properti untuk pointTransition
     */
    public static final String PROPERTY_POINT_TRANSITION = "PROPERTY_POINT_TRANSITION";
    /**
     * Properti untuk image
     */
    public static final String PROPERTY_IMAGE = "PROPERTY_IMAGE";
    /**
     * Properti untuk blindsStep
     */
    public static final String PROPERTY_BLINDS_STEP = "PROPERTY_BLINDS_STEP";
    private ImageTransition imageTransition;
    private Point pointTransition;
    private BufferedImage image;
    private Animator animator;
    private int effect,  i,  blindsStep;
    private AlphaComposite alphaComposite;
    private double step,  center,  x,  y,  width,  height,  stepW,  stepH,  temp;
    private Double rectangleDouble;
    private Area area,  area2;
    private Point centerPoint;
    private TransitionEvent transitionEvent;
// </editor-fold>
    /**
     * Memubuat EImageTransition baru
     */
    public EImageTransition() {
        // memanggil superclass
        super();

        // mengubah properti opaque manjadi false
        super.setOpaque(false);
    }

    /**
     * Mendapatkan nilai blinds step
     * @return int
     */
    public int getBlindsStep() {
        if (blindsStep <= 1) {
            return 5;
        }
        return blindsStep;
    }

    /**
     * mengubah nilai blinds step, jika blindstep bernilai kurang dari atau sama 
     * dengan 1, maka akan dirubah menjadi 5
     * @param blindsStep
     */
    public void setBlindsStep(int blindsStep) {
        // validasi blindstep
        if (blindsStep <= 1) {
            blindsStep = 5;
        }

        // mendapatkan nilai lama
        int oldValue = getBlindsStep();

        // mengubah nilai blindstep lama
        this.blindsStep = blindsStep;

        if (oldValue != blindsStep) {
            // memberi tahu bahwa nilai blindstep berubah
            firePropertyChange(PROPERTY_BLINDS_STEP, oldValue, blindsStep);
        }
    }

    /**
     * Mendapatkan gambar EImageTransition
     * @return BufferedImage
     */
    public BufferedImage getImage() {
        return image;
    }

    /**
     * Mengubah gambar EImageTransition
     * @param image gambar baru
     */
    public void setImage(BufferedImage image) {
        // mendapatkan gambar lama
        BufferedImage oldValue = getImage();

        // mengubah gambar lama
        this.image = image;

        if (oldValue != image) {
            // memberitahu propertyChangeListener bahwa image berubah
            firePropertyChange(PROPERTY_IMAGE, oldValue, image);
        }
    }

    /**
     * Mendapatkan nilai point transition
     * @return Point
     */
    public Point getPointTransition() {
        return pointTransition;
    }

    /**
     * Mengubah nilai point transition
     * @param pointTransition nilai baru
     */
    public void setPointTransition(Point pointTransition) {
        // mendapatkan nilai lama
        Point oldValue = getPointTransition();

        // mengubah nilai lama
        this.pointTransition = pointTransition;

        if (oldValue != pointTransition) {
            // memberitahu propertyChangeListener bahwa pointTransition berubah
            firePropertyChange(PROPERTY_POINT_TRANSITION, oldValue, pointTransition);
        }
    }

    /**
     * Mendapatkan {@link ImageTransition} milik EImageTransition
     * @return ImageTransition
     */
    public ImageTransition getImageTransition() {
        return imageTransition;
    }

    /**
     * Mengubah nilai {@link ImageTransition} lama
     * @param imageTransition nilai baru
     */
    public void setImageTransition(ImageTransition imageTransition) {
        // mendapatkan nilai lama
        ImageTransition oldValue = getImageTransition();

        // mengubah image transition
        this.imageTransition = imageTransition;

        if (oldValue != imageTransition) {
            //memberitahu propertyCHangeListener bahwa nilai imageTransition berubah
            firePropertyChange(PROPERTY_IMAGE_TRANSITION, oldValue, imageTransition);
        }
    }

    /**
     * Menyuruh EImageTransition untuk memulai efek transisi dengan akselerator 
     * sebesar 0.2F dan dekselerator sebesar 0.4F
     * @param milisecond lama waktu transisi
     */
    public void startTransition(int milisecond) {
        startTransition(milisecond, 0.2F, 0.4F);
    }

    /**
     * Menyuruh EImageTransition untuk memulai efek transisi
     * @param miliSecond lama waktu transisi
     * @param acelerator nilai akselerator
     * @param deceleator nilai dekselerator
     */
    public void startTransition(int miliSecond, float acelerator, float deceleator) {
        // Mengecek apakah animator sedang berjalan
        if (getAnimator().isRunning()) {
            // Jika animator sedang berjalan maka animator akan diberhentikan
            getAnimator().stop();
        }

        // mengubah durasi animator
        getAnimator().setDuration(miliSecond);
        // mengubah akselerator animator
        getAnimator().setAcceleration(acelerator);
        // mengubah dekselerator animator
        getAnimator().setDeceleration(deceleator);
        // menjalankan animator
        getAnimator().start();

        // menjalankan aksi onStart()
        fireTransitionListenerOnStart(getTransitionEvent());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null && imageTransition != null && pointTransition != null 
                && getAnimator().isRunning()) {
            paintTransition(g);
        }
    }

    /**
     * Melakukan penggambaran efek transisi
     * @param g
     */
    protected void paintTransition(Graphics g) {
        // mendapatkan Graphics2D
        Graphics2D g2 = (Graphics2D) g.create();

        // apakah area null
        if (area == null) {
            // jika null, maka buat area baru
            area = new Area();
        } else {
            // jika tidak null, maka hilangkan seluruh area
            area.reset();
        }

        try {
            if (imageTransition == ImageTransition.BLINDS_HORIZONTAL) {
                paintTransitionBlindsHorizontal(g2);
            } else if (imageTransition == ImageTransition.BLINDS_VERTICAL) {
                paintTransitionBlindsVertical(g2);
            } else if (imageTransition == ImageTransition.BOX_IN) {
                paintTransitionBoxIn(g2);
            } else if (imageTransition == ImageTransition.BOX_OUT) {
                paintTransitionBoxOut(g2);
            } else if (imageTransition == ImageTransition.FADE) {
                paintTransitionFade(g2);
            } else if (imageTransition == ImageTransition.SPLIT_HORIZONTAL_IN) {
                paintTransitionSplitHorizontalIn(g2);
            } else if (imageTransition == ImageTransition.SPLIT_HORIZONTAL_OUT) {
                paintTransitionSplitHorizontalOut(g2);
            } else if (imageTransition == ImageTransition.SPLIT_VERTICAL_IN) {
                paintTransitionSplitVerticalIn(g2);
            } else if (imageTransition == ImageTransition.SPLIT_VERTICAL_OUT) {
                paintTransitionSplitVerticalOut(g2);
            } else if (imageTransition == ImageTransition.WIPE_DOWN) {
                paintTransitionWipeDown(g2);
            } else if (imageTransition == ImageTransition.WIPE_LEFT) {
                paintTransitionWipeLeft(g2);
            } else if (imageTransition == ImageTransition.WIPE_RIGHT) {
                paintTransitionWipeRight(g2);
            } else if (imageTransition == ImageTransition.WIPE_UP) {
                paintTransitionWipeUp(g2);
            } else if (imageTransition == ImageTransition.COVER_DOWN) {
                paintTransitionCoverDown(g2);
            } else if (imageTransition == ImageTransition.COVER_LEFT) {
                paintTransitionCoverLeft(g2);
            } else if (imageTransition == ImageTransition.COVER_RIGHT) {
                paintTransitionCoverRight(g2);
            } else if (imageTransition == ImageTransition.COVER_UP) {
                paintTransitionCoverUp(g2);
            } else if (imageTransition == ImageTransition.MINIMIZE_HORIZONTAL) {
                paintTransitionMinimizeHorizontal(g2);
            } else if (imageTransition == ImageTransition.MINIMIZE_VERTICAL) {
                paintTransitionMinimizeVertical(g2);
            } else if (imageTransition == ImageTransition.FADE_AND_ROTATE) {
                paintTransitionFadeAndRotate(g2);
            }
        } finally {
            // menghilangkan Graphics2D
            g2.dispose();
        }
    }
    // <editor-fold defaultstate="collapsed" desc="Temp Code">
    /**
     * Mendapatkan animator EImageTransition
     * @return Animator
     */
    protected Animator getAnimator() {
        if (animator == null) {
            animator = new Animator(0, new PropertySetter(this, "effect", 0, 101));
        }
        return animator;
    }

    /**
     * Mendapatkan alpha composite
     * @return AlphaCOmposite
     */
    protected AlphaComposite getAlphaComposite() {
        if (alphaComposite == null) {
            alphaComposite = AlphaComposite.SrcOver;
        }
        return alphaComposite;
    }

    /**
     * mendapatkan lokasi tengah
     * @return Point
     */
    protected Point getCenterPoint() {
        if (centerPoint == null) {
            centerPoint = new Point();
        }
        return centerPoint;
    }

    /**
     * Mendapatkan rectangle double
     * @return Rectangle Double
     */
    protected Double getRectangleDouble() {
        if (rectangleDouble == null) {
            rectangleDouble = new Double();
        }
        return rectangleDouble;
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Deprecated Code">
    /**
     * DILARANG MEMANGGIL METODE INI
     * @return int nilai effect
     * @deprecated 
     */
    @Deprecated
    public int getEffect() {
        return effect;
    }

    /**
     * DILARAN MENGUBAH NILAI EFFECT
     * @param effect
     * @deprecated
     */
    @Deprecated
    public void setEffect(int effect) {
        this.effect = effect;
        repaint();

        if (effect >= 100) {
            // menjalankan aksi onFinish()
            fireTransitionListenerOnFinish(getTransitionEvent());
        }
    }

    @Override
    @Deprecated
    public void setOpaque(boolean isOpaque) {
        super.setOpaque(false);
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Event and Listener Code">
    /**
     * Menambahkan aksi Transition Listener
     * @param listener 
     */
    public void addTransitionListener(TransitionListener listener) {
        listenerList.add(TransitionListener.class, listener);
    }

    /**
     * Menghapus sebuah listener
     * @param listener
     */
    public void removeTransitionListener(TransitionListener listener) {
        listenerList.remove(TransitionListener.class, listener);
    }

    /**
     * Menjalankan aksi {@link TransitionListener#onStart(open.usu.swing.event.TransitionEvent) }
     * @param event
     */
    protected void fireTransitionListenerOnStart(TransitionEvent event) {
        for (TransitionListener listenr : listenerList.getListeners(TransitionListener.class)) {
            listenr.onStart(event);
        }
    }

    /**
     * Menjalankan aksi {@link TransitionListener#onFinish(open.usu.swing.event.TransitionEvent) }
     * @param event
     */
    protected void fireTransitionListenerOnFinish(TransitionEvent event) {
        for (TransitionListener listenr : listenerList.getListeners(TransitionListener.class)) {
            listenr.onFinish(event);
        }
    }

    private TransitionEvent getTransitionEvent() {
        if (transitionEvent == null) {
            transitionEvent = new TransitionEvent(this);
        }
        return transitionEvent;
    }
// </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Paint Image Transition Code">
    /**
     * Menggambar efek Blinds Horizontal
     * @param g2
     */
    protected void paintTransitionBlindsHorizontal(Graphics2D g2) {
        temp = (getImage().getHeight() * 1.0) / (getBlindsStep() * 1.0);
        step = temp / 100.0;

        height = temp - (step * effect);
        for (i = 0; i < getBlindsStep(); i++) {
            y = getPointTransition().y + (temp * i);
            getRectangleDouble().setRect(getPointTransition().x, y, getImage().getWidth(), height);
            area2 = new Area(getRectangleDouble());
            area.add(area2);
        }
        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * Menggambar efect Blinds Vertical
     * @param g2
     */
    protected void paintTransitionBlindsVertical(Graphics2D g2) {
        temp = (getImage().getWidth() * 1.0) / (getBlindsStep() * 1.0);
        step = temp / 100.0;

        width = temp - (step * effect);
        for (i = 0; i < getBlindsStep(); i++) {
            x = getPointTransition().x + (temp * i);
            getRectangleDouble().setRect(x, getPointTransition().y, width, getImage().getHeight());
            area2 = new Area(getRectangleDouble());
            area.add(area2);
        }
        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * Menggambar efect Box In
     * @param g2
     */
    protected void paintTransitionBoxIn(Graphics2D g2) {
        getCenterPoint().setLocation(getImage().getWidth() / 2.0, getImage().getHeight() / 2.0);

        stepW = getImage().getWidth() / 100.0;
        stepH = getImage().getHeight() / 100.0;

        width = getImage().getWidth() - (stepW * effect);
        height = getImage().getHeight() - (stepH * effect);
        x = getCenterPoint().x - (width / 2.0) + getPointTransition().x;
        y = getCenterPoint().y - (height / 2.0) + getPointTransition().y;

        getRectangleDouble().setRect(x, y, width, height);
        area2 = new Area(getRectangleDouble());
        area.add(area2);

        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * Mengambar efek Box Out
     * @param g2
     */
    protected void paintTransitionBoxOut(Graphics2D g2) {
        getCenterPoint().setLocation(getImage().getWidth() / 2.0, getImage().getHeight() / 2.0);

        stepW = getImage().getWidth() / 100.0;
        stepH = getImage().getHeight() / 100.0;

        width = (stepW * effect);
        height = (stepH * effect);
        x = getCenterPoint().x - (width / 2.0) + getPointTransition().x;
        y = getCenterPoint().y - (height / 2.0) + getPointTransition().y;

        getRectangleDouble().setRect(x, y, width, height);

        area = new Area(GraphicUtilities.getRectangleImage(getImage(), getPointTransition()));
        area2 = new Area(getRectangleDouble());
        area.exclusiveOr(area2);

        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * Menggambar efek Fade
     * @param g2
     */
    protected void paintTransitionFade(Graphics2D g2) {
        alphaComposite = getAlphaComposite().derive(1.0F - (this.effect / 100.0F));

        g2.setClip(GraphicUtilities.getRectangleImage(getImage(), getPointTransition()));
        g2.setComposite(getAlphaComposite());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * Menggambar efek Split Horizontal In
     * @param g2
     */
    protected void paintTransitionSplitHorizontalIn(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        center = getPointTransition().y + getImage().getHeight() / 2.0;

        height = getImage().getHeight() - (step * this.effect);
        y = center - (height / 2.0);

        getRectangleDouble().setRect(getPointTransition().x, y,
                getImage().getWidth(), height);

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * Menggambar efek SPlit Horizontal Out
     * @param g2
     */
    protected void paintTransitionSplitHorizontalOut(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        height = (step * this.effect);
        center = getPointTransition().y + getImage().getHeight() / 2.0;
        y = center - (height / 2.0);

        getRectangleDouble().setRect(getPointTransition().x, y, getImage().getWidth(), height);

        area = new Area(GraphicUtilities.getRectangleImage(getImage(), getPointTransition()));
        area2 = new Area(getRectangleDouble());
        area.exclusiveOr(area2);

        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * Mengambar efek Split Vertical In
     * @param g2
     */
    protected void paintTransitionSplitVerticalIn(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        width = getImage().getWidth() - (step * this.effect);
        center = getPointTransition().x + getImage().getWidth() / 2.0;
        x = center - (width / 2.0);

        getRectangleDouble().setRect(x, getPointTransition().y, width, getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * Menggambar efek Split Vertical Out
     * @param g2
     */
    protected void paintTransitionSplitVerticalOut(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        width = (step * this.effect);
        center = getPointTransition().x + getImage().getWidth() / 2.0;
        x = center - (width / 2.0);

        getRectangleDouble().setRect(x, getPointTransition().y, width, getImage().getHeight());

        area = new Area(GraphicUtilities.getRectangleImage(getImage(), getPointTransition()));
        area2 = new Area(getRectangleDouble());
        area.exclusiveOr(area2);

        g2.setClip(area);
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().x, null);
    }

    /**
     * menggambar efek Wipe Down
     * @param g2
     */
    protected void paintTransitionWipeDown(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        y = (getPointTransition().y + (step * this.effect));
        height = (getImage().getHeight() - (step * this.effect));

        getRectangleDouble().setRect(getPointTransition().x, y,
                getImage().getWidth(), height);

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Wipe Left
     * @param g2
     */
    protected void paintTransitionWipeLeft(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        width = getImage().getWidth() - (step * this.effect);

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y, width,
                getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Wipe Right
     * @param g2
     */
    protected void paintTransitionWipeRight(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        x = getPointTransition().x + (step * this.effect);
        width = getImage().getWidth() - (step * this.effect);

        getRectangleDouble().setRect(x, getPointTransition().y, width, getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Wipe Up
     * @param g2
     */
    protected void paintTransitionWipeUp(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        height = getImage().getHeight() - (step * this.effect);

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), height);

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Cover Down
     * @param g2
     */
    protected void paintTransitionCoverDown(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        y = getPointTransition().y + step * effect;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, (int) y, null);
    }

    /**
     * menggambar efek Cover Left
     * @param g2
     */
    protected void paintTransitionCoverLeft(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        x = getPointTransition().x - step * effect;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), (int) x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Cover Right
     * @param g2
     */
    protected void paintTransitionCoverRight(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        x = getPointTransition().x + step * effect;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), (int) x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Cover Up
     * @param g2
     */
    protected void paintTransitionCoverUp(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        y = getPointTransition().y - step * effect;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());

        g2.setClip(getRectangleDouble());
        g2.drawImage(getImage(), getPointTransition().x, (int) y, null);
    }

    /**
     * menggambar efek Minimize Horizontal
     * @param g2
     */
    protected void paintTransitionMinimizeHorizontal(Graphics2D g2) {
        step = getImage().getHeight() / 100.0;

        height = getImage().getHeight() - step * effect;
        y = getPointTransition().y + (getImage().getHeight() - height) / 2.0;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());
        g2.setClip(getRectangleDouble());

        g2.drawImage(getImage(), getPointTransition().x, (int) y,
                getImage().getWidth(), (int) height, null);
    }

    /**
     * menggambar efek fade and rotate
     * @param g2
     */
    protected void paintTransitionFadeAndRotate(Graphics2D g2) {
        alphaComposite = getAlphaComposite().derive(1.0F - (this.effect / 100.0F));
        step = 360 / 100.0;

        g2.setClip(GraphicUtilities.getRectangleImage(getImage(), getPointTransition()));
        g2.rotate(Math.toRadians(step * effect), getPointTransition().x + getImage().getWidth() / 2,
                getPointTransition().y + getImage().getHeight() / 2);
        g2.setComposite(getAlphaComposite());
        g2.drawImage(getImage(), getPointTransition().x, getPointTransition().y, null);
    }

    /**
     * menggambar efek Minimize Vertical
     * @param g2
     */
    protected void paintTransitionMinimizeVertical(Graphics2D g2) {
        step = getImage().getWidth() / 100.0;

        width = getImage().getWidth() - step * effect;
        x = getPointTransition().y + (getImage().getWidth() - width) / 2.0;

        getRectangleDouble().setRect(getPointTransition().x, getPointTransition().y,
                getImage().getWidth(), getImage().getHeight());
        g2.setClip(getRectangleDouble());

        g2.drawImage(getImage(), (int) x, getPointTransition().y, (int) width, getImage().getHeight(), null);
    }
// </editor-fold>
}
